home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1996 June: Reference Library / Dev.CD Jun 96 RL / Dev.CD Jun 96 RL.toast / What's New? / Tool Chest / Text / WASTE 1.2a6 / WASTE Demo ƒ / WEDemoEvents.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-04-22  |  9.8 KB  |  492 lines  |  [TEXT/CWIE]

  1. /*
  2.     WASTE Demo Project:
  3.     Events Handling
  4.  
  5.     Copyright © 1993-1996 Marco Piovanelli
  6.     All Rights Reserved
  7.  
  8.     C port by John C. Daub
  9. */
  10.  
  11. #ifndef __APPLEEVENTS__
  12. #include <AppleEvents.h>
  13. #endif
  14.  
  15. #ifndef __AEREGISTRY__
  16. #include <AERegistry.h>
  17. #endif
  18.  
  19. #ifndef __DISKINIT__
  20. #include <DiskInit.h>
  21. #endif
  22.  
  23. #ifndef __TEXTSERVICES__
  24. #include <TextServices.h>
  25. #endif
  26.  
  27. #ifndef __WEDEMOAPP__
  28. #include "WEDemoIntf.h"
  29. #endif
  30.  
  31. static UInt32        sSleepTime = 0;            // sleep time for WaitNextEvent()
  32. static RgnHandle    sMouseRgn = nil;        // mouse region for WaitNextEvent()
  33.  
  34.  
  35. void AdjustCursor( Point mouseLoc, RgnHandle mouseRgn )
  36. {
  37.     WindowRef window;
  38.  
  39.     // by default, set mouseRgn to the whole QuickDraw coordinate plane,
  40.     // so that we never get mouse moved events
  41.  
  42.     SetRectRgn( mouseRgn, -SHRT_MAX, -SHRT_MAX, SHRT_MAX, SHRT_MAX );
  43.  
  44.     // give text services a chance to set the cursor shape
  45.  
  46.     if ( gHasTextServices )
  47.     {
  48.         if ( SetTSMCursor( mouseLoc ) )
  49.             return;
  50.     }
  51.  
  52.     // if there is a window open, give WEAdjustCursor an opportunity to set the cursor
  53.     // WEAdjustCursor intersects mouseRgn (if supplied) with a region within which
  54.     // the cursor is to retain its shape
  55.     // (if the cursor is outside the view region, this is subtracted from mouseRgn )
  56.  
  57.     if ( ( window = FrontWindow( ) ) != nil )
  58.     {
  59.         if ( WEAdjustCursor( mouseLoc, mouseRgn, GetWindowWE( window ) ) )
  60.             return;
  61.     }
  62.  
  63.     // set the cursor to the arrow cursor
  64.  
  65.     SetCursor( &qd.arrow );
  66. }
  67.  
  68. void DoMouseDown( const EventRecord *event )
  69. {
  70.     WindowRef window;
  71.     short partCode;
  72.  
  73.     // find out where this click when down in
  74.  
  75.     partCode = FindWindow( event->where, &window );
  76.  
  77.     // dispatch on partCode
  78.  
  79.     switch ( partCode )
  80.     {
  81.         case inMenuBar:
  82.             PrepareMenus( );
  83.             DoMenuChoice( MenuSelect( event->where ) );
  84.             break;
  85.  
  86.         case inSysWindow:
  87.             // ??? shouldn't SystemClick be defined as
  88.             //     SystemClick(const EventRecord *, WindowRef) ???
  89.             SystemClick( event, (WindowPtr) window );
  90.             break;
  91.  
  92.         case inContent:
  93.             if ( DoContent( event->where, event, window ) )
  94.             {
  95.                 SelectWindow( window );
  96.             }
  97.             break;
  98.  
  99.         case inDrag:
  100.             DoDrag( event->where, window );
  101.             break;
  102.  
  103.         case inGrow:
  104.             DoGrow( event->where, window );
  105.             break;
  106.  
  107.         case inGoAway:
  108.             if ( TrackGoAway( window, event->where ) )
  109.             {
  110.                 if ( DoClose( closingWindow, savingAsk, window ) != noErr )
  111.                 {
  112.                     // insert error handling
  113.                 }
  114.             }
  115.             break;
  116.  
  117.         case inZoomIn:
  118.         case inZoomOut:
  119.             if ( TrackBox( window, event->where, partCode ) )
  120.             {
  121.                 DoZoom( partCode, window );
  122.             }
  123.             break;
  124.     }    // switch
  125. }
  126.  
  127. void DoKeyDown( const EventRecord *event )
  128. {
  129.     short key;
  130.     Boolean isCmdKey;
  131.  
  132.     // extract character code from event message
  133.  
  134.     key = ( event->message & charCodeMask );
  135.  
  136.     // is this a command+key combo?
  137.  
  138.     isCmdKey = ( ( event->modifiers & cmdKey ) != 0 );
  139.  
  140.     // map function keys to the equivalent command+key combos
  141.     // note that all fuction keys generate the same code, i.e. 0x10
  142.  
  143.     if ( key == 0x10 )
  144.     {
  145.         isCmdKey = true;
  146.  
  147.         switch( ( event->message & keyCodeMask ) >> 8 )
  148.         {
  149.             case keyF1:
  150.                 key = 'z';
  151.                 break;
  152.  
  153.             case keyF2:
  154.                 key = 'x';
  155.                 break;
  156.  
  157.             case keyF3:
  158.                 key = 'c';
  159.                 break;
  160.  
  161.             case keyF4:
  162.                 key = 'v';
  163.                 break;
  164.  
  165.             default:
  166.                 key = 0;
  167.  
  168.         }    // switch
  169.     }    // if
  170.  
  171.     // command + printable character combos are routed to MenuKey( )
  172.     // but be sure to pass command + arrow key combos to WEKey( )
  173.  
  174.     if ( isCmdKey && (key >= 0x20 ) )
  175.     {
  176.         PrepareMenus( );
  177.         DoMenuChoice( MenuKey( key ) );
  178.     }
  179.     else
  180.     {
  181.         DoKey( key, event );
  182.     }
  183. }
  184.  
  185. void DoDiskEvent( const EventRecord *event )
  186. {
  187.     Point dialogCorner;
  188.  
  189.     if ( ( event->message >> 16) != noErr )
  190.     {
  191.         SetPt( &dialogCorner, 112, 80 );
  192.         DIBadMount( dialogCorner, event->message );
  193.     }
  194. }
  195.  
  196. void DoOSEvent( const EventRecord *event )
  197. {
  198.     short        osMessage;
  199.     WindowRef    window;
  200.  
  201.     // extract the OS message field from the event record
  202.  
  203.     osMessage = ( event->message & osEvtMessageMask) >> 24 ;
  204.  
  205.     // dispatch on osMessage
  206.  
  207.     switch( osMessage )
  208.     {
  209.         case suspendResumeMessage:
  210.             if ( ( window = FrontWindow( ) ) != nil )
  211.             {
  212.                 DoActivate( (event->message & resumeFlag) != 0, window );
  213.             }
  214.             break;
  215.  
  216.         case mouseMovedMessage:
  217.             // nothing
  218.             break;
  219.     }
  220. }
  221.  
  222. void DoHighLevelEvent( const EventRecord *event )
  223. {
  224.     AEProcessAppleEvent( event );
  225. }
  226.  
  227. void DoNullEvent( const EventRecord *event )
  228. {
  229. #pragma unused (event)
  230.  
  231.     WindowRef window;
  232.  
  233.     if ( ( window = FrontWindow( ) ) != nil )
  234.     {
  235.         WEIdle( &sSleepTime, GetWindowWE(window) );
  236.     }
  237.     else
  238.     {
  239.         sSleepTime = LONG_MAX;
  240.     }
  241. }
  242.  
  243. void DoWindowEvent( const EventRecord *event )
  244. {
  245.     WindowRef window;
  246.  
  247.     // the message field of the event record contains the window reference
  248.  
  249.     window = (WindowRef) event->message;
  250.  
  251.     // make sure this window is an application window; check the windowKind field
  252.  
  253.     if ( GetWindowKind( window ) != userKind )
  254.         return;
  255.  
  256.     switch ( event->what )
  257.     {
  258.         case updateEvt:
  259.             DoUpdate( window );
  260.             break;
  261.  
  262.         case activateEvt:
  263.             DoActivate( ( event->modifiers & activeFlag) != 0, window );
  264.             break;
  265.     }
  266. }
  267.  
  268. void ProcessEvent( void )
  269. {
  270.     EventRecord event;
  271.     Boolean gotEvent;
  272.  
  273.     gotEvent = WaitNextEvent( everyEvent, &event, sSleepTime, sMouseRgn );
  274.  
  275.     // give text services a chance to intercept this event
  276.     // if TSMEvent( ) handles the event, it will set event.what to nullEvent
  277.  
  278.     if ( gHasTextServices )
  279.     {
  280.         TSMEvent( &event );
  281.     }
  282.  
  283.     // adjust cursor shape and set mouse region
  284.     // (we assume event.where is the current mouse position in global coordinates
  285.     // if event.what <= osEvt; high-level events store the event ID there)
  286.  
  287.     if ( event.what <= osEvt )
  288.     {
  289.         AdjustCursor( event.where, sMouseRgn );
  290.     }
  291.  
  292.     // dispatch on event.what
  293.  
  294.     switch( event.what )
  295.     {
  296.         case nullEvent:
  297.             DoNullEvent( &event );
  298.             break;
  299.  
  300.         case mouseDown:
  301.             DoMouseDown( &event);
  302.             break;
  303.  
  304.         case keyDown:
  305.         case autoKey:
  306.             DoKeyDown( &event );
  307.             break;
  308.  
  309.         case updateEvt:
  310.         case activateEvt:
  311.             DoWindowEvent( &event );
  312.             break;
  313.  
  314.         case diskEvt:
  315.             DoDiskEvent( &event );
  316.             break;
  317.  
  318.         case osEvt:
  319.             DoOSEvent( &event );
  320.             break;
  321.  
  322.         case kHighLevelEvent:
  323.             DoHighLevelEvent( &event );
  324.             break;
  325.     }    // switch
  326.  
  327.     if ( gotEvent )
  328.     {
  329.         sSleepTime = 0;  // force early idle after non-idle event
  330.     }
  331. }
  332.  
  333. OSErr GotRequiredParams( const AppleEvent *ae )
  334. {
  335.     DescType actualType;
  336.     Size actualSize;
  337.     OSErr err;
  338.  
  339.     err = AEGetAttributePtr( ae, keyMissedKeywordAttr, typeWildCard, &actualType, nil, 0, &actualSize );
  340.  
  341.     return    ( err == errAEDescNotFound ) ? noErr :
  342.             ( err == noErr ) ? errAEParamMissed : err;
  343. }
  344.  
  345. static pascal OSErr    HandleOpenDocument( const AppleEvent *ae, AppleEvent *reply, long refCon )
  346. {
  347. #pragma unused ( reply, refCon )
  348.     AEDescList        docList;
  349.     AEKeyword        keyword;
  350.     DescType        actualType;
  351.     Size            actualSize;
  352.     long            numberOfDocuments, i;
  353.     FSSpec            fileSpec;
  354.     OSErr            err;
  355.  
  356.     docList.descriptorType = typeNull;
  357.     docList.dataHandle = nil;
  358.  
  359.     // extract direct parameter from the Apple event
  360.  
  361.     if ( ( err = AEGetParamDesc( ae, keyDirectObject, typeAEList, &docList ) ) != noErr )
  362.         goto cleanup;
  363.  
  364.     // perform the recommended check for additional required parameters
  365.  
  366.     if ( ( err = GotRequiredParams( ae ) ) != noErr )
  367.         goto cleanup;
  368.  
  369.     // count the items in the list of aliases
  370.  
  371.     if ( ( err = AECountItems( &docList, &numberOfDocuments ) ) != noErr )
  372.         goto cleanup;
  373.  
  374.     for ( i = 1; i <= numberOfDocuments; i++ )
  375.     {
  376.         // coerce the nth alias to a file system specification record
  377.  
  378.         if ( ( err = AEGetNthPtr( &docList, i, typeFSS, &keyword, &actualType,
  379.                 &fileSpec, sizeof( fileSpec ), &actualSize ) ) != noErr )
  380.             goto cleanup;
  381.  
  382.         // open the specified file
  383.  
  384.         if ( ( err = CreateWindow( &fileSpec ) ) != noErr )
  385.             goto cleanup;
  386.     }
  387.  
  388. cleanup:
  389.     AEDisposeDesc( &docList );
  390.     return err;
  391. }
  392.  
  393. static pascal OSErr    HandleOpenApplication( const AppleEvent *ae, AppleEvent *reply, long refCon )
  394. {
  395. #pragma unused ( reply, refCon )
  396.     OSErr        err;
  397.  
  398.     // perform the recommended check for additional required parameters
  399.  
  400.     if ( ( err = GotRequiredParams( ae ) ) != noErr )
  401.         goto cleanup;
  402.  
  403.     // create a new window from scratch
  404.  
  405.     err = CreateWindow( nil );
  406.  
  407. cleanup:
  408.     return err;
  409. }
  410.  
  411. static pascal OSErr    HandleQuitApplication( const AppleEvent *ae, AppleEvent *reply, long refCon )
  412. {
  413. #pragma unused (reply, refCon)
  414.  
  415.     AEKeyword        optKey;
  416.     DescType        actualType;
  417.     Size            actualSize;
  418.     SavingOption    saving;
  419.     OSErr            err;
  420.  
  421.     // default saving option is savingAsk;
  422.  
  423.     saving = savingAsk;
  424.  
  425.     // extract optional save options
  426.  
  427.     if ( ( err = AEGetParamPtr( ae, keyAESaveOptions, typeEnumerated, &actualType, &optKey, sizeof( optKey ), &actualSize ) ) == noErr )
  428.     {
  429.         if ( optKey == kAEYes )
  430.         {
  431.             saving = savingYes;
  432.         }
  433.         else if (optKey == kAENo )
  434.         {
  435.             saving = savingNo;
  436.         }
  437.         else if ( optKey != kAEAsk )
  438.         {
  439.             err = paramErr;    // for want of a better code
  440.             goto cleanup;
  441.         }
  442.     }
  443.  
  444.     // perform the recommended check for additional required parameters
  445.  
  446.     if ( ( err = GotRequiredParams( ae ) ) != noErr )
  447.         goto cleanup;
  448.  
  449.     // actually do the quit stuff
  450.  
  451.     err = DoQuit( saving );
  452.  
  453. cleanup:
  454.     return err;
  455. }
  456.  
  457. OSErr InitializeEvents( void )
  458. {
  459.     OSErr    err;
  460.  
  461.     // allocate space for the mouse region
  462.  
  463.     sMouseRgn = NewRgn( );
  464.  
  465.     // install AppleEvent handlers for the Required Suite
  466.  
  467.     if ( ( err = AEInstallEventHandler( kCoreEventClass, kAEOpenApplication, NewAEEventHandlerProc( HandleOpenApplication ), 0, false ) ) != noErr )
  468.         goto cleanup;
  469.  
  470.     if ( ( err = AEInstallEventHandler( kCoreEventClass, kAEOpenDocuments, NewAEEventHandlerProc( HandleOpenDocument ), kDoOpen, false ) ) != noErr )
  471.         goto cleanup;
  472.  
  473.     if ( ( err = AEInstallEventHandler( kCoreEventClass, kAEPrintDocuments, NewAEEventHandlerProc( HandleOpenDocument ), kDoPrint, false ) ) != noErr )
  474.         goto cleanup;
  475.  
  476.     if ( ( err = AEInstallEventHandler( kCoreEventClass, kAEQuitApplication, NewAEEventHandlerProc( HandleQuitApplication ), 0, false ) ) != noErr )
  477.         goto cleanup;
  478.  
  479.     // install Apple event handlers for a subset of the Core suite
  480.  
  481.     if ( ( err = InstallCoreHandlers( ) ) != noErr )
  482.         goto cleanup;
  483.  
  484.     // install Apple event handlers for inline input
  485.  
  486.     if ( ( err = WEInstallTSMHandlers( ) ) != noErr )
  487.         goto cleanup;
  488.  
  489. cleanup:
  490.     return err;
  491. }
  492.